package com.stylefeng.guns.modular.code.controller;

import com.baomidou.mybatisplus.generator.config.po.TableField;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.toolkit.StringUtils;
import com.stylefeng.guns.core.base.controller.BaseController;
import com.stylefeng.guns.core.config.properties.DruidProperties;
import com.stylefeng.guns.core.util.ToolUtil;
import com.stylefeng.guns.generator.action.config.WebGeneratorConfig;
import com.stylefeng.guns.generator.action.model.GenQo;
import com.stylefeng.guns.modular.code.factory.DefaultTemplateFactory;
import com.stylefeng.guns.modular.code.service.TableService;
import com.stylefeng.guns.modular.system.model.ColModel;
import com.stylefeng.guns.modular.system.service.IColModelService;

import io.swagger.annotations.ApiOperation;

import java.util.Date;
import java.util.List;
import java.util.TooManyListenersException;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.SessionAttributes;

/**
 * 代码生成控制器
 *
 * @author fengshuonan
 * @Date 2017年11月30日16:39:19
 */
@Controller
@RequestMapping("/code")
@SessionAttributes(value = {"genQo","tables"})
public class CodeController extends BaseController {

    private static String PREFIX = "/code";

    @Autowired
    private TableService tableService;
    
    @Autowired
    private IColModelService colModelService;
    

    @Autowired
    private DruidProperties druidProperties;

    /**
     * 跳转到代码生成主页
     */
    @RequestMapping("")
    public String blackboard(Model model) {
        model.addAttribute("tables", tableService.getAllTables());
        model.addAttribute("params", DefaultTemplateFactory.getDefaultParams());
        model.addAttribute("templates", DefaultTemplateFactory.getDefaultTemplates());
        return PREFIX + "/code.html";
    }

    /**
     * 生成代码
     */
    @ApiOperation("生成代码")
    @RequestMapping(value = "/generate", method = RequestMethod.POST)
    @ResponseBody
    public Object generate(GenQo genQo, Model model) {
        genQo.setUrl(druidProperties.getUrl());
        genQo.setUserName(druidProperties.getUsername());
        genQo.setPassword(druidProperties.getPassword());
        WebGeneratorConfig webGeneratorConfig = new WebGeneratorConfig(genQo);
        
        model.addAttribute("genQo", genQo);
        
        if (genQo.getTemplatePrefixPath().equalsIgnoreCase("gunsTemplate/jqGrid")) {
            //webGeneratorConfig.doMpGeneration();
        	generateColModel(webGeneratorConfig.getTableInfo());
        } else {
            webGeneratorConfig.doMpGeneration();
            webGeneratorConfig.doGunsGeneration();
        }
        return SUCCESS_TIP;
    }
    
    /**
     * 生成jqgrid代码
     */
    @ApiOperation("生成jqgrid代码")
    @RequestMapping(value = "/generatejqgrid", method = RequestMethod.POST)
    @ResponseBody
    public Object generateJqGrid(@ModelAttribute GenQo genQo, Model model) {
        genQo.setUrl(druidProperties.getUrl());
        genQo.setUserName(druidProperties.getUsername());
        genQo.setPassword(druidProperties.getPassword());
        WebGeneratorConfig webGeneratorConfig = new WebGeneratorConfig(genQo);
        
        List<ColModel> cols = bulidColSetting(genQo.getTableName());
        //model.addAttribute("genQo", genQo);
        //model.addAttribute("cols", cols);
        
        webGeneratorConfig.doMpGeneration();	//??
        webGeneratorConfig.doGunsGeneration(cols);
        
        return SUCCESS_TIP;
    }
    
    private List<ColModel> bulidColSetting(String tableName){
    	boolean isend = false;
    	String newline = System.lineSeparator() +  "\t\t\t\t\t\t";	//美化生成代码
		Wrapper<ColModel> wrapper = new EntityWrapper<ColModel>();
		wrapper.and().eq("table_name", tableName).orderBy("sort_num");
		List<ColModel> list = colModelService.selectList(wrapper);
		for(ColModel cm : list) {
			isend = false;
			StringBuffer sBuffer = new StringBuffer("{ label: '").append(cm.getColLabel());
		    sBuffer.append("', name: '").append(cm.getEntityName())
		    			.append("', index: '").append(cm.getIndexName()).append("'");
		    if (cm.getKey()) {
		    	sBuffer.append(", key: true, hidden: true");
		    } else {
		    	sBuffer.append(", hidden: ").append(cm.getHidden());
		    }
		    sBuffer.append(", width: ").append(cm.getWidth())
	    			.append(", search: ").append(cm.getSearch())
	    			.append(", resizable: ").append(cm.getResizable())
	    			.append(", fixed: ").append(cm.getFixed())
	    			.append(", align: '").append(cm.getAlign())
	    			.append("', sortable: ").append(cm.getSortable())
	    			.append(", editable: ").append(cm.getEditable());

		    
	    	//默认操作eq(=)
		    cm.setSearchOptionsSopt(ToolUtil.isEmpty(cm.getSearchOptionsSopt())? "\"eq\"":cm.getSearchOptionsSopt());
		    
		    String searchoptions = "";
		    if (cm.getMultiple() && cm.getFdSelect()) {
			    searchoptions = new StringBuffer().append(newline)
			    		.append(", searchoptions: {sopt: [\"cn\",\"nc\"]").toString(); //花括号}未关闭
		    } else {
			    searchoptions = new StringBuffer().append(newline)
			    		.append(", searchoptions: {sopt: [").append(cm.getSearchOptionsSopt()).append("]").toString(); //花括号}未关闭
		    }
		    
		    if (cm.getColSimpleType().equals("date")) {
		    	sBuffer.append(searchoptions).append(", dataInit: datePick, attr:{title:'选择日期'}}");
		    	if (cm.getEditable()) { 
		    		sBuffer.append(", edittype: \"text\", editoptions: {dataInit: datePick, attr:{title:'选择日期'}}}, ");
		    	}
		    	else {
		    		sBuffer.append("},");
		    	}
		    	isend = true;
		    }
		    
		    if (!isend) {
			    if (cm.getFdSelect() && !cm.getColSimpleType().equals("boolean")) {
			    	sBuffer.append(", stype:'select', edittype: 'select'")
			    		.append(", formatter: 'select', multiple: ").append(cm.getMultiple())
			    		.append(searchoptions).append(", value: ':;' + select_var_").append(cm.getEntityName()).append("}, ")	//searchoptions结束
			    		.append(newline)
			    		.append("editoptions: { multiple: ").append(cm.getMultiple())
			    		.append(", value: ':;' + select_var_") .append(cm.getEntityName()).append("}");
			    } else if (cm.getColSimpleType().equals("boolean"))  {
			    	//searchoptions:{sopt: ["eq"], value: "1:是;0:否"}
		    		sBuffer.append(", stype:'select', edittype: 'checkbox', formatter: 'checkbox'")
		    			.append(searchoptions).append(", value: '1:是;0:否'}, ")	//searchoptions结束
		    			.append(newline)
		    			.append("editoptions: { value: '1:0', defaultValue: '1'}");
			    } else {
			    	sBuffer.append(searchoptions).append("}"); //searchoptions结束
			    }
		    }
		    
		    if (!isend) {
		    	if (cm.getColSimpleType().equals("boolean")) {
		    		//formatter: 'checkbox', editable: true, edittype: "checkbox", editoptions: { value: "1:0", defaultValue: "1" }},
		    	}
		    }
		    
		    if (!isend) {
		    	sBuffer.append("},");	//一列定义结束
		    }
		    cm.setColSetting(sBuffer.toString());
		    colModelService.updateById(cm);
		}
		list = colModelService.selectList(wrapper);		
		return list;    	
    }
    
    
    
    /**
     * 配置JQGRID
     */
    private void generateColModel(TableInfo tblinfo) {
        int i = 0;	//排序计数器
    	//删除不存在的列
    	Wrapper<ColModel> wrapper = new EntityWrapper<ColModel>();
		wrapper.eq("table_name", tblinfo.getName()).and().notIn("col_name", tblinfo.getFieldNames().replaceAll(", ", ","));
		colModelService.delete(wrapper); 
		
    	for(TableField tf: tblinfo.getFields()) {
    		wrapper = new EntityWrapper<ColModel>();
			wrapper.eq("table_name", tblinfo.getName()).and().eq("col_name", tf.getName());
    		if (colModelService.selectCount(wrapper) == 0 ) {	//只增加新增的列，其余的保留设置
	    		ColModel cm = new ColModel();
	            String simpletype = ToolUtil.sqlSimpleMapType(tf.getColumnType().getType()).toLowerCase();
	    		
				cm.setTableName(tblinfo.getName());
				cm.setColName(tf.getName());
				//对is开头的布尔型属性进行特殊处理
			    if (simpletype.equals("boolean") && tf.getPropertyName().substring(2).equalsIgnoreCase("is")) { 
			    	cm.setEntityName(StringUtils.firstCharToLower(org.apache.commons.lang.StringUtils.right(tf.getPropertyName(), tf.getPropertyName().length()-2)));
			    } else {
			    	cm.setEntityName(tf.getPropertyName());
			    }
		    	cm.setIndexName(tf.getPropertyName());
				
				//cm.setEntityName(tf.getPropertyName());
				cm.setColSimpleType(simpletype);
				cm.setColLabel(ToolUtil.getFieldTitle(tf.getComment())); 
				cm.setKey(tf.isKeyFlag());
				cm.setGen(true);
				cm.setHidden(tf.isKeyFlag() ? true : false); 
				cm.setWidth("boolean".equals(simpletype) ? 30 : 100);
				if ("text".equals(simpletype)) {
					cm.setAlign("left");
				} else if ("numeric".equals(simpletype)) {
					cm.setAlign("right");
				} else if ("date".equals(simpletype)) {
					cm.setAlign("center");
				} else if ("boolean".equals(simpletype)) {
					cm.setAlign("center");
				} else {
					cm.setAlign("left");
				}
				cm.setSearch(true); 
				cm.setResizable(true); 
				cm.setFixed(true);
				cm.setSortable(true);
				if ("text".equals(simpletype)) {
					cm.setSearchOptionsSopt("\"cn\",\"eq\",\"nc\"");
				} else if ("numeric".equals(simpletype)) {
					cm.setSearchOptionsSopt("\"ge\",\"gt\",\"le\",\"lt\",\"ne\"");
				} else if ("date".equals(simpletype)) {
					cm.setSearchOptionsSopt("\"eq\",\"ge\",\"le\",\"ne\"");
				} else if ("boolean".equals(simpletype)) {
					cm.setSearchOptionsSopt("\"eq\"");
				} else {
					cm.setSearchOptionsSopt("'cn','eq','ne','le','ge'");
				}
				cm.setFdSelect(false);
				cm.setEditable(false);
				cm.setGenRefVar(false);
				cm.setSortNum(i*10);
				cm.setCreated(new Date());
				colModelService.insert(cm);
    		}
			i++;
    	}
    }
}
